package be.kuleuven.thesis.parsers;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;


public class VCFreader {
	private static final Logger log = Logger.getLogger(VCFreader.class.getName());
	
	
	public VariantList read(String filename) throws IOException {
		log.info("vcf.read():Reading " + filename);
		String[] name = filename.split("/");
		batchName = name[name.length - 1].replace(".vcf.gz", "");
		
		VariantList variants = new VariantList();
		BufferedReader br;
		
		if(filename.endsWith(".gz")){
			InputStream fileStream = new FileInputStream(filename);
			InputStream gzipStream = new GZIPInputStream(fileStream);
			Reader decoder = new InputStreamReader(gzipStream,"UTF-8");
			gzipStream.close();
			br = new BufferedReader(decoder);
		}else{
			br = new BufferedReader(new FileReader(filename));
		}
		
		String s;
		for(s = br.readLine(); null != s; s=br.readLine()){
			s=s.trim();
			if (s.length() > 0) {
				if(s.substring(0,11).equals("##reference")){
					String[] rf = s.split("/");
					referenceFile = rf[rf.length - 1];
				}else if (s.substring(0,2).equals("##")) {
                    //ignore comment lines
                } else if (s.substring(0,2).equals("#C")){
                	initSampleList(s);	
                }else {
                	VariantFeature v = parseLine(s);
                	if (v != null){
                		variants.add(v);
                	}
                }
                	
                }
			
		}
		br.close();
		System.out.println(variants.size() + " variations");
		return variants;
	}
	
	private String[] sampleList = null;
	
	private void initSampleList(String s){
		assert(s.substring(0,2).equals("#C"));
		
		int start = 0;
		int end = 0;
		
		start = s.indexOf("FORMAT", start);
		start = s.indexOf('\t', start) +1;
		end = s.indexOf('#',start);
		
		String line = null;
		if(end < 0){
			line = new String(s.substring(start)).trim();	
		}else{
			line = new String(s.substring(start, end)).trim();
		}
		
		sampleList = line.split("\t");
		System.out.println(sampleList.length + " samples.");
	}
	
	public int sampleSize(){
		return sampleList.length;
	}
	
	private VariantFeature parseLine(String s){
		int start = 0;
		int end = 0;
		
		start = end;
		end = s.indexOf('\t', start);
		String chrom = s.substring(start, end).trim();
		
		start = end + 1;
        end = s.indexOf('\t', start);
        Integer position;
        position = Integer.parseInt(s.substring(start, end).trim());
        
        start = end + 1;
        end = s.indexOf('\t', start);
		String localId = s.substring(start, end).trim();
		
		start = end + 1;
        end = s.indexOf('\t', start);
        String refAllele = s.substring(start, end).trim();
		
        start = end + 1;
        end = s.indexOf('\t', start);
        String altAllele = s.substring(start, end).trim();
        
        start = end + 1;
        end = s.indexOf('\t', start);
        Float quality = Float.parseFloat(s.substring(start, end).trim());
        
        start = end + 1;
        end = s.indexOf('\t', start);
        
        start = end + 1;
        end = s.indexOf('\t', start);
        String info = s.substring(start, end).trim();
        System.out.println(info);
        
        start = end + 1;
        end = s.indexOf('\t', start);
        String format = s.substring(start, end).trim();
        //System.out.println(format);
        
        start = end + 1;
        end = s.indexOf('#', start);
        String genotypes = null;
        HashMap<String,String> sampleGenotypes = new HashMap<String, String>();
        if(end < 0){
			genotypes = new String(s.substring(start)).trim();	
		}else{
			genotypes = new String(s.substring(start, end)).trim();
		}
        String[] gtys = genotypes.split("\t");
        for(int i = 0; i<gtys.length; i++){
        	if(! gtys[i].contains("0[\\/\\|]0")){
        		sampleGenotypes.put(sampleList[i], gtys[i]);
        	}
        }
        
        return new VariantFeature(chrom, position, localId, refAllele, altAllele, quality, 
        		info, format, sampleGenotypes);    
	}
	
	private String referenceFile;
	
	public String getReference(){
		return referenceFile;
	}

	private String batchName;
	
	public String getBatchName(){
		return batchName;
	}

}
